/*
外观模式（Facade Pattern）是一种结构型设计模式，它提供了一个统一的接口，用于访问子系统中的一组接口。
外观模式定义了一个高层接口，使得子系统更易于使用。

外观模式由以下几个角色组成：

● 外观（Facade）：提供了一个简单的接口，用于访问子系统中的一组接口。外观对象知道哪些子系统类负责处理请求，将请求代理给适当的子系统对象。
● 子系统（Subsystem）：实现了子系统的功能，处理外观对象指派的任务。

使用外观模式可以隐藏子系统的复杂性，简化客户端与子系统之间的交互。
客户端只需要通过外观对象来与子系统进行交互，而无需了解子系统的具体实现。
外观模式符合开闭原则，使得系统更加灵活，易于扩展和维护。

下面是一个使用外观模式的C语言例程，用于实现一个计算器程序，其中计算器是子系统，外观对象提供了简单的接口来访问计算器的功能：
*/

#include <stdio.h>
#include <stdlib.h>

// 子系统
typedef struct
{
    int result;
} Calculator;

void add(Calculator *calculator, int x, int y)
{
    calculator->result = x + y;
}

void subtract(Calculator *calculator, int x, int y)
{
    calculator->result = x - y;
}

void multiply(Calculator *calculator, int x, int y)
{
    calculator->result = x * y;
}

void divide(Calculator *calculator, int x, int y)
{
    if (y != 0)
    {
        calculator->result = x / y;
    }
    else
    {
        printf("Error: Division by zero\n");
    }
}

// 外观
typedef struct
{
    Calculator calculator;
    void (*add)(int, int);		//这几行可删？ 
    void (*subtract)(int, int);	//这几行可删？ 
    void (*multiply)(int, int);	//这几行可删？ 
    void (*divide)(int, int);	//这几行可删？ 
} CalculatorFacade;

void addWrapper(int x, int y)
{
    CalculatorFacade *facade = (CalculatorFacade *)malloc(sizeof(CalculatorFacade));
    add(&(facade->calculator), x, y);
    printf("Addition result: %d\n", facade->calculator.result);
}

void subtractWrapper(int x, int y)
{
    CalculatorFacade *facade = (CalculatorFacade *)malloc(sizeof(CalculatorFacade));
    subtract(&(facade->calculator), x, y);
    printf("Subtraction result: %d\n", facade->calculator.result);
}

void multiplyWrapper(int x, int y)
{
    CalculatorFacade *facade = (CalculatorFacade *)malloc(sizeof(CalculatorFacade));
    multiply(&(facade->calculator), x, y);
    printf("Multiplication result: %d\n", facade->calculator.result);
}

void divideWrapper(int x, int y)
{
    CalculatorFacade *facade = (CalculatorFacade *)malloc(sizeof(CalculatorFacade));
    divide(&(facade->calculator), x, y);
    printf("Division result: %d\n", facade->calculator.result);
}

int main()
{
    // 使用外观对象访问计算器功能
    addWrapper(5, 3);
    subtractWrapper(5, 3);
    multiplyWrapper(5, 3);
    divideWrapper(5, 3);
    divideWrapper(5, 0);

    return 0;
}

/*
在上面的例程中，首先定义了子系统Calculator，其中实现了加法、减法、乘法和除法的功能。
然后，定义了外观CalculatorFacade，其中持有一个子系统对象的引用，并提供了简单的接口来访问子系统的功能。
在外观中，通过包装子系统的接口方法来实现外观的接口方法。
在main函数中，使用外观对象访问计算器的功能，并打印出计算结果。

通过使用外观模式，我们可以将复杂的子系统封装起来，提供一个简单的接口给客户端使用。
这样可以降低客户端的复杂性，同时也提高了代码的可维护性和可扩展性。
外观模式适用于需要简化复杂子系统的接口的场景，或者需要将客户端与子系统解耦的场景。
*/